package com.ibm.risk.irmp.base.dict.service.impl;

import com.ibm.risk.irmp.base.dict.dao.BaseDictItemRepository;
import com.ibm.risk.irmp.base.dict.dao.PBaseDictGroupRepository;
import com.ibm.risk.irmp.base.dict.entity.BaseDictGroup;
import com.ibm.risk.irmp.base.dict.entity.BaseDictItem;
import com.ibm.risk.irmp.base.dict.service.IDataDictService;
import com.ibm.risk.irmp.base.dict.vo.BaseDictItemTreeVo;
import com.ibm.risk.irmp.base.dict.vo.BaseDictItemVo;
import com.ibm.risk.irmp.base.dict.vo.BaseDictVo;
import com.ibm.risk.irmp.common.exception.BusinessException;
import com.ibm.risk.irmp.common.utils.DaoUtils;
import com.ibm.risk.irmp.common.vo.CodeLabelVo;
import jakarta.persistence.EntityManager;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Primary
@Transactional(readOnly = true)
@CacheConfig(cacheNames = "IrmpParamDataCache")
public class DataDictServiceImpl implements IDataDictService {

    @Autowired
    private PBaseDictGroupRepository baseDictGroupRepository;

    @Autowired
    private BaseDictItemRepository baseDictItemRepository;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private DaoUtils daoUtils;

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

//    @Transactional(readOnly = true)
//    public List<Map<String, Object>> getTableList2() {
//        //构造字典数据类型的树形目录
//        String sql = "SELECT '0' AS id, NULL AS pid, '数据字典' AS NAME, 0 AS seq FROM dual\n" + "UNION\n" + "SELECT t.id, '0' AS pid, t.NAME, 1 AS seq FROM RI_BASE_DICT t WHERE t.id <> 'SYSTEM_CONFIG'\n" + "UNION\n" + "SELECT t.id, d.ID AS pid, t.label AS NAME, t.seq FROM RI_BASE_DICT_ITEM t\n" + "  INNER JOIN RI_BASE_DICT d ON t.GROUP_ID = d.CODE WHERE t.PARENT_ID = '0' AND t.GROUP_ID <> 'SYSTEM_CONFIG'\n" + "UNION\n" + "SELECT t.id, t.parent_id AS pid, t.label AS NAME, t.seq FROM RI_BASE_DICT_ITEM t\n" + "  INNER JOIN RI_BASE_DICT d ON t.GROUP_ID = d.CODE WHERE " +
//                //                "  t.id IN (\n" +
//                //                "  SELECT a.PARENT_ID FROM RI_BASE_DICT_ITEM a WHERE a.PARENT_ID IS NOT NULL  AND a.GROUP_ID <> 'SYSTEM_CONFIG')\n" +
//                "   t.PARENT_ID <> '0' " + "ORDER BY pid, seq";
//        List<Map<String, String>> dataTypes = daoUtils.pagedQueryCamelCase(sql, 0, 99999, new HashMap<>());
//        return buildDataTree(dataTypes, null);
//    }

    //    @Override
    // TODO: remove it
    public List<? extends BaseDictVo> getDictList() {

        //构造字典数据类型的树形目录
        List<BaseDictGroup> grps = baseDictGroupRepository.findAll();
//        List<Map<String, Object>> dataTypes = daoUtils.pagedQuery(sql, 0, 99999, new HashMap<>());
//        List<Map<String, Object>> params = new ArrayList<>();
//        //add first layer
//        Map<String, Object> root = new HashMap<>();
//        root.put("expand", true);
//        root.put("isLeaf", false);
//        root.put("key", "0");
//        root.put("title", "数据字典");
//        root.put("value", "");
//
//        params.add(root);
//
//        List<Map<String, Object>> children = new ArrayList<>();
//        root.put("children", children);
//
//        for (Map<String, Object> paramItem : dataTypes) {
//            Map<String, Object> item = new HashMap<>();
//            item.put("title", paramItem.get("name"));
//            item.put("value", paramItem.get("pid"));
//            item.put("key", paramItem.get("id"));
//            item.put("expand", false);
//            item.put("isLeaf", true);
//            children.add(item);
//        }
        return grps;
    }

    //    @Override
    public List<BaseDictItemVo> getGroupItemList(String group) {
        List<BaseDictItem> items = baseDictItemRepository.getBaseDictItemByGroupCodeOrderBySeq(group);
        return items.stream().map(item -> {
            BaseDictItemVo vo = new BaseDictItemVo();
            itemCopier.copy(item, vo, null);
            return vo;
        }).toList();
    }


    private List<Map<String, Object>> buildDataTree(List<Map<String, String>> dataTypes, String pid) {
        //树形目录下拉框
        List<Map<String, Object>> params = new ArrayList<>();
        for (Map<String, String> paramItem : dataTypes) {
            if (StringUtils.equals(pid, (String) paramItem.get("pid"))) {
                Map<String, Object> item = new HashMap<>();
                item.put("title", paramItem.get("name"));
                item.put("value", paramItem.get("pid"));
                item.put("key", paramItem.get("id"));

                if (pid == null || "0".equals(pid)) {
                    item.put("expanded", true);
                } else {
                    item.put("expanded", false);
                }

                List<Map<String, Object>> children = new ArrayList<>();
                if (paramItem.get("id") != null) {
                    children = buildDataTree(dataTypes, (String) paramItem.get("id"));
                }
                if (children.size() == 0) {
                    item.put("isLeaf", true);
                } else {
                    item.put("isLeaf", false);
                }
                item.put("children", children);
                params.add(item);
            }
        }
        return params;
    }
//    BeanCopier paramCopier = BeanCopier.create(BaseDictItem.class, DictParamVo.class, false);
    BeanCopier itemCopier = BeanCopier.create(BaseDictItem.class, BaseDictItemVo.class, false);
//
//    @Override
//    public List<DictParamVo> getItemList(String group, Integer level) {
//        if (level == null) {
//            level = 0;
//        }
//        List<BaseDictItem> items;
//        if (level == 0) {
//            items = baseDictItemRepository.findByGroupCodeAndParentIdIsNullOrderBySeq(group);
//        } else {
//            items = baseDictItemRepository.findByGroupCodeOrderBySeq(group);
//        }
//        return items.stream().map(item -> {
//            DictParamVo vo = new DictParamVo();
//            paramCopier.copy(item, vo, null);
//            return vo;
//        }).toList();
//
//    }

    @Override
    //@Cacheable(key = "'BASE_DICT:' + methodName + args")
    public List<BaseDictItemTreeVo> getItemTree(String group) {
        List<BaseDictItem> items = baseDictItemRepository.findByGroupCodeAndParentIdIsNullOrderBySeq(group);
        List<BaseDictItemTreeVo> nodes = toTreeVos(items);
//        TreeLikeUtils.expandTree(items);
        return nodes;
    }

    private static List<BaseDictItemTreeVo> toTreeVos(List<BaseDictItem> items) {
        List<BaseDictItemTreeVo> nodes = new ArrayList<>(items.size());
        for (BaseDictItem item : items) {
            BaseDictItemTreeVo node = new BaseDictItemTreeVo();
            if (!item.getChildren().isEmpty()) {
                node.setChildren(toTreeVos(item.getChildren()));
            } else {
                item.setChildren(null);
            }
            BeanCopier.create(BaseDictItem.class, BaseDictItemTreeVo.class, false).copy(item, node, null);
            nodes.add(node);
        }
        return nodes;
    }

    @Override
    public List<CodeLabelVo> getItemCodeLabels(String groupCode, String category) {
        List<CodeLabelVo> items;
        if (StringUtils.isEmpty(category)) {
            items = baseDictItemRepository.findByGroupCodeOrderBySeq(groupCode);
        } else {
            items = baseDictItemRepository.findByGroupCodeAndCategoryOrderBySeq(groupCode, category);
        }
        return items;
    }

    @Override
    public Map<String, String> getItemCodeLabelMap(String groupCode, String category) {
        List<CodeLabelVo> vos = getItemCodeLabels(groupCode, category);
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        vos.forEach(vo -> map.put(vo.code(), vo.label()));
        return map;
    }

    @Override
    @Transactional(readOnly = false)
    public Boolean saveDict(Map<String, Object> saveParmas) {
        String parentId = (String) saveParmas.get("parentId");
        Integer level = (Integer) saveParmas.get("level");

        Object save = null;
        // 如果选择的是第一级
        if (level >= 0) {

            BaseDictGroup baseDictGroup = new BaseDictGroup();
//            baseDictGroup.setLang((String) saveParmas.get("lang"));
//            baseDictGroup.setId((String) saveParmas.get("id"));
            baseDictGroup.setCode((String) saveParmas.get("code"));
            baseDictGroup.setName((String) saveParmas.get("name"));
//            if (StringUtils.isEmpty(baseDictGroup.getId())) {
//                baseDictGroup.setId(baseDictGroup.getCode());
//            }

            save = baseDictGroupRepository.save(baseDictGroup);
        } else if (level == 1) {
            BaseDictItem baseDictItem = new BaseDictItem();
            baseDictItem.setGroupCode(parentId);
            baseDictItem.setId((String) saveParmas.get("id"));
            baseDictItem.setCode((String) saveParmas.get("code"));
//            baseDictItem.setLang((String) saveParmas.get("lang"));
            baseDictItem.setLabel((String) saveParmas.get("name"));
            baseDictItem.setSeq(StringUtils.isNumeric(String.valueOf(saveParmas.get("seq"))) ? Integer.parseInt(String.valueOf(saveParmas.get("seq"))) : 1);
            if (StringUtils.isEmpty(baseDictItem.getId())) {
                baseDictItem.setId(baseDictItem.getCode() + baseDictItem.getSeq());
            }
            save = baseDictItemRepository.save(baseDictItem);
        } else {
            //查找Group_ID
            Optional<BaseDictItem> dictItemEntity = baseDictItemRepository.findById(parentId);
            BaseDictItem baseDictItem = new BaseDictItem();
            baseDictItem.setGroupCode(dictItemEntity.get().getGroupCode());
//            baseDictItem.setParentId((String) saveParmas.get("parentId"));
            baseDictItem.setId((String) saveParmas.get("id"));
            baseDictItem.setCode((String) saveParmas.get("code"));
//            baseDictItem.setLang((String) saveParmas.get("lang"));
            baseDictItem.setLabel((String) saveParmas.get("name"));
            baseDictItem.setSeq(StringUtils.isNumeric(String.valueOf(saveParmas.get("seq"))) ? Integer.parseInt(String.valueOf(saveParmas.get("seq"))) : 1);
            if (StringUtils.isEmpty(baseDictItem.getId())) {
                baseDictItem.setId(baseDictItem.getCode() + baseDictItem.getSeq());
            }
            save = baseDictItemRepository.save(baseDictItem);
        }

        return save != null;
    }

    /**
     * 删除字典类型及其代码
     */
    @Transactional(readOnly = false)
    public Boolean deleteDict(Integer level, String dictType) {
        if (StringUtils.isEmpty(dictType)) {
            throw new BusinessException("请输入字典类型代码");
        }
        if (level >= 0) {
            baseDictItemRepository.deleteByGroupCode(dictType);
            baseDictGroupRepository.deleteByCode(dictType);
        } else if (level > 1) {
            //Todo: may need to query code, not id
            baseDictItemRepository.deleteByParentId(dictType);
            baseDictItemRepository.deleteById(dictType);
        }

        return true;
    }

    @Override
    @Transactional(readOnly = false)
    public Boolean saveDictItem(BaseDictItem entity) {
        //刷新配置缓存
//        RwaApplicationConfig.clear();

        if (StringUtils.isEmpty(entity.getId())) {
            entity.setId(entity.getCode() + entity.getSeq());
        }

        //查找上级GroupID
//        if (StringUtils.equals(entity.getGroupCode(), entity.getParentId())) {
//            Optional<BaseDictItem> parentOptional = pBaseDictItemRepository.findById(entity.getParentId());
//            if (parentOptional.isPresent()) {
//                entity.setGroupCode(parentOptional.get().getGroupCode());
//            }
//        }

        BaseDictItem save = baseDictItemRepository.save(entity);
        return save != null;
    }

    @Override
    @Transactional(readOnly = false)
    public Boolean deleteDictItem(String id) {
        //刷新配置缓存
//        RwaApplicationConfig.clear();

        baseDictItemRepository.deleteById(id);
        return true;
    }

    @Override
    public BaseDictItem getDefaultItemByGroup(String groupId) {
        List<BaseDictItem> defaultDataDates = baseDictItemRepository.findByGroupCodeAndIsDefault("DATA_DATE", true);
        if (defaultDataDates.isEmpty()) {
            return null;
        }
        return defaultDataDates.get(0);
    }


}
